/*
 * @Author: january.cjy
 * @Date: 2021-09-27 19:50:08
 * @Last Modified by: january.cjy
 * @Last Modified time: 2021-11-02 19:43:04
 */
#pragma once

#include<CmgFileFeature.h>

#include "clang/Basic/SourceManager.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Basic/IdentifierTable.h"

namespace cmg {
using namespace llvm;
using namespace clang;

class CmgPPCallbacks : public clang::PPCallbacks {
public:
  typedef PPCallbacks base;
  CmgPPCallbacks(SourceManager &sm,FileFeature &feature);

  // #include
  virtual void InclusionDirective(SourceLocation HashLoc,
                                  const Token &IncludeTok, StringRef FileName,
                                  bool IsAngled, CharSourceRange FilenameRange,
                                  const FileEntry *File, StringRef SearchPath,
                                  StringRef RelativePath,
                                  const clang::Module *Imported,
                                  SrcMgr::CharacteristicKind FileType) override;

  // 文件读写
  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
                           SrcMgr::CharacteristicKind FileType,
                           FileID PrevFID = FileID()) override;

  // 文件省略
  virtual void FileSkipped(const FileEntryRef &SkippedFile,
                           const Token &FilenameTok,
                           SrcMgr::CharacteristicKind FileType) override;

  // 宏扩展
  virtual void MacroExpands(const Token &MacroNameTok,
                            const MacroDefinition &MD, SourceRange Range,
                            const MacroArgs *Args) override;

  // 宏定义
  virtual void MacroDefined(const Token &MacroNameTok,
                            const MacroDirective *MD) override;

  // 宏解定义
  virtual void MacroUndefined(const Token &MacroNameTok,
                              const MacroDefinition &MD,
                              const MacroDirective *Undef) override;

  // #if defined
  virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
                       SourceRange Range) override;

  // #ifdef
  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
                     const MacroDefinition &MD) override;

  // #ifndef
  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
                      const MacroDefinition &MD) override;

private:
  SourceManager &sm;
  FileFeature &fileFeature;
};
} // namespace cmg